# gozerlib/wave/bot.py
#
#

""" google wave bot. """

## gozerlib imports

from gozerlib.persist.persist import Persist
from gozerlib.botbase import BotBase
from gozerlib.plugins import plugs
from gozerlib.utils.generic import getversion
from gozerlib.utils.auth import finduser
from gozerlib.callbacks import callbacks
from gozerlib.outputcache import add

from event import WaveEvent
from waves import Wave

## waveapi imports

from waveapi import events
from waveapi import model
from waveapi import robot
from waveapi import document
from waveapi import robot_abstract

## generic imports

import logging
import cgi
import os
import time

waves = {}

class WaveBot(BotBase, robot.Robot):

    """ 
        bot to implement google wave stuff. 

        :param name: bot's name
        :type param: string
        :param image_url: url pointing to the bots image
        :type image_url: string
        :param version: the bots version 
        :type version: string
        :param profile_url: url pointing to the bots profile
        :type profile_url: string

    """

    def __init__(self, name='cmndbot', 
                 image_url='http://cmndbot.appspot.com/assets/favicon.png',
                 version='1',
                 profile_url='http://cmndbot.appspot.com/'):
        BotBase.__init__(self, name)
        robot.Robot.__init__(self, name=name, version=version, image_url=image_url, profile_url=profile_url)
        self.RegisterHandler(events.BLIP_SUBMITTED, self.OnBlipSubmitted)
        self.RegisterHandler(events.WAVELET_PARTICIPANTS_CHANGED, self.OnParticipantsChanged)
        self.RegisterHandler(events.WAVELET_SELF_ADDED, self.OnRobotAdded)
        self.type = "wave"
        self.iswave = True
        self.channels = Persist("gozerstore" + os.sep + "fleet" + os.sep + self.name + os.sep + "channels")
        self.waves = waves
 
    def OnParticipantsChanged(self, properties, context):

        """ invoked when any participants have been added/removed. """

        event = WaveEvent()
        event.parse(self, properties, context)
        event.cbtype = "WAVELET_PARTICAPANTS_CHANGED"
        callbacks.check(self, event)

    def OnRobotAdded(self, properties, context):

        """ invoked when the robot has been added. """

        time.sleep(1)
        root_wavelet = context.GetRootWavelet()
        root_wavelet.CreateBlip().GetDocument().AppendText(getversion('WAVE'))
        time.sleep(1)
        root_wavelet.CreateBlip().GetDocument().AppendText('see !help')
        #blip = context.GetBlipById(properties['blipId'])
        #blip.CreateChild().GetDocument().SetText(getversion('WAVE'))
        #blip.CreateChild().GetDocument().SetText(' .. see !help')
        waveid = root_wavelet.waveId
        #waveid = properties['blipId']
        self.waves[waveid] = Wave(waveid)
        self.waves[waveid].parse(properties, context)
        logging.info('joined "%s" (%s) wave' % (waveid, root_wavelet.title))
        event = WaveEvent()
        event.parse(self, properties, context)
        event.cbtype = "WAVELET_SELF_ADDED"
        callbacks.check(self, event)

    def OnBlipSubmitted(self, properties, context):

        """ new blip added. here is where the command dispatching takes place. """

        event = WaveEvent()
        event.parse(self, properties, context)
        root_wavelet = context.GetRootWavelet()
        #waveid = properties['blipId']
        #blip = context.GetBlipById(properties['blipId'])
        waveid = root_wavelet.waveId
        self.waves[waveid] = Wave(waveid)
        self.waves[waveid].parse(properties, context)
        logging.debug("added %s (%s) to the waves list" % (waveid, root_wavelet.title))

        #rootid = root_wavelet.GetId()

        event.auth = event.userhost
        event.waveid = waveid
        event.cbtype = "BLIP_SUBMITTED"
        event.channel = waveid

        if event.poller:
            event.cbtype = "POLLER"
            callbacks.check(self, event)
            return
            
        if len(event.txt) >= 2 and event.txt[0] == '!':
            event.txt = event.txt[1:]
            plugs.dispatch(self, event)
        elif ":cmnd:" in event.txt:
            (pre, post) = event.txt.split(':cmnd:', 1)
            event.txt = post.strip()
            plugs.dispatch(self, event)

        callbacks.check(self, event)

    def say(self, waveid, txt):

        """
            output to the root id. 

            :param waveid: id of the wave 
            :type waveid: string
            :param txt: text to output
            :type txt: string
            :rtype: None

        """

        add(waveid, [txt, ])

    def newwave(self, context, participants=None):

        """
            create a new wave. 

        """

        newwave = robot_abstract.NewWave(context, participants=participants)
        logging.debug('newwave: %s' % dir(newwave))
        return newwave
